﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Linq;
using System.Threading.Tasks;
using System.Windows.Forms;
using DevExpress.XtraEditors;
using System.Runtime.InteropServices;

using System.Threading;
using System.Drawing.Printing;
using System.Drawing.Drawing2D;
using System.Drawing.Imaging;
using System.IO;

namespace Lamex.mMES.UI
{
    public partial class frmMES_Layout_Operation : DevExpress.XtraEditors.XtraForm
    {

        //c# winfrom 放大镜功能
        //https://www.cnblogs.com/mby2012/p/7324398.html

        private bool blIsDrawRectangle = true;
        private Point ptBegin = new Point();
        Thread thDraw;
        delegate void myDrawRectangel();
        myDrawRectangel myDraw;
        //定义图片的width和height
        int Width_Pic1 = 0;
        int Height_Pic2 = 0;
        int e_X_Pic1 = 0;
        int e_Y_Pic1 = 0;
        static bool IsShowDrawRect = true;
        static bool IsMouseWheel = false;
        double step = 1.2;
        int x;
        int y;
        public frmMES_Layout_Operation()
        {
            InitializeComponent();
        }

        private void frmMES_Layout_Operation_Load(object sender, EventArgs e)
        {
            Cursor = Cursors.Hand;

            this.panel1.MouseWheel += new MouseEventHandler(panel1_MouseWheel);
            this.pictureBox1.MouseWheel += new MouseEventHandler(pictureBox1_MouseWheel);
            this.pictureBox1.SizeMode = PictureBoxSizeMode.StretchImage;

            //c# 设置控件图片，导致图片被占用无法删除问题
            //https://www.cnblogs.com/zuoz/p/7158722.html            //pictureBox加载图片方法
            string filepath = @"\\Tx-fs10\tx-fs1\LAMEX\IE\Layout\Image\Lamex_Factory_Layout_Vx.png";

            //方法一：此方法文件被占用，无法进行更新操作
            //pictureBox1.Load(filepath);

            //方法二：将Image类转换成Bitmap类，此方法未测试成功
            //System.Drawing.Image img = System.Drawing.Image.FromFile(filepath);
            //System.Drawing.Image bmp = new System.Drawing.Bitmap(img);
            //pictureBox1.Image = bmp;????
            //img.Dispose();

            ////方法三：从流中读取
            FileStream fileStream = new FileStream(filepath, FileMode.Open, FileAccess.Read);
            pictureBox1.Image = Image.FromStream(fileStream);
            fileStream.Close();
            fileStream.Dispose(); 

            //因放大镜不流畅，所以默认不启用
            blIsDrawRectangle = false;
            IsShowDrawRect = false;
            //myDraw = new myDrawRectangel(ShowDrawRectangle);
            //thDraw = new Thread(Run);
            //thDraw.Start();
        }

        private void frmMES_Layout_Operation_Resize(object sender, EventArgs e)
        {
            pictureBox1.Width = panel1.Width;
            pictureBox1.Height = panel1.Height;
            Width_Pic1 = pictureBox1.Width;
            Height_Pic2 = pictureBox1.Height;
        }

        #region 图片放大缩小平移

        private bool isMouseDown = false;
        private Point mouseOffset;

        private void panel1_MouseWheel(object sender, MouseEventArgs e)
        {
            //double step = 1.2;
            if (e.Delta > 0)
            {
                if (pictureBox1.Height >= Screen.PrimaryScreen.Bounds.Height * 10)
                    return;
                pictureBox1.Height = (int)(pictureBox1.Height * step);
                pictureBox1.Width = (int)(pictureBox1.Width * step);

                int px = Cursor.Position.X - pictureBox1.Location.X;
                int py = Cursor.Position.Y - pictureBox1.Location.Y;
                int px_add = (int)(px * (step - 1.0));
                int py_add = (int)(py * (step - 1.0));
                pictureBox1.Location = new Point(pictureBox1.Location.X - px_add, pictureBox1.Location.Y - py_add);
                Application.DoEvents();
            }
            else
            {
                pictureBox1.Height = (int)(pictureBox1.Height / step);
                pictureBox1.Width = (int)(pictureBox1.Width / step);

                int px = Cursor.Position.X - pictureBox1.Location.X;
                int py = Cursor.Position.Y - pictureBox1.Location.Y;
                int px_add = (int)(px * (1.0 - 1.0 / step));
                int py_add = (int)(py * (1.0 - 1.0 / step));
                pictureBox1.Location = new Point(pictureBox1.Location.X + px_add, pictureBox1.Location.Y + py_add);
                Application.DoEvents();
            }
            Width_Pic1 = pictureBox1.Width;
            Height_Pic2 = pictureBox1.Height;
        }

        private void pictureBox1_MouseWheel(object sender, MouseEventArgs e)
        {
           // double step = 1.2;
            if (e.Delta > 0)
            {
                if (pictureBox1.Height >= Screen.PrimaryScreen.Bounds.Height * 10)
                    return;
                pictureBox1.Height = (int)(pictureBox1.Height * step);
                pictureBox1.Width = (int)(pictureBox1.Width * step);

                int px = Cursor.Position.X - pictureBox1.Location.X;
                int py = Cursor.Position.Y - pictureBox1.Location.Y;
                int px_add = (int)(px * (step - 1.0));
                int py_add = (int)(py * (step - 1.0));
                pictureBox1.Location = new Point(pictureBox1.Location.X - px_add, pictureBox1.Location.Y - py_add);
                Application.DoEvents();
            }
            else
            {
                pictureBox1.Height = (int)(pictureBox1.Height / step);
                pictureBox1.Width = (int)(pictureBox1.Width / step);

                int px = Cursor.Position.X - pictureBox1.Location.X;
                int py = Cursor.Position.Y - pictureBox1.Location.Y;
                int px_add = (int)(px * (1.0 - 1.0 / step));
                int py_add = (int)(py * (1.0 - 1.0 / step));
                pictureBox1.Location = new Point(pictureBox1.Location.X + px_add, pictureBox1.Location.Y + py_add);
                Application.DoEvents();
            }
            Width_Pic1 = pictureBox1.Width;
            Height_Pic2 = pictureBox1.Height;
            //e_X_Pic1 = e.Location.X;
            //e_Y_Pic1 = e.Location.Y;
            IsMouseWheel = true;
        }

        private void pictureBox1_MouseMove(object sender, MouseEventArgs e)
        {
            if (isMouseDown)//图片平移
            {
                int left = pictureBox1.Left + e.X - mouseOffset.X;
                int top = pictureBox1.Top + e.Y - mouseOffset.Y;
                pictureBox1.Location = new Point(left, top);
            }

            if (IsShowDrawRect)
            {
                #region 设置背景色不闪烁
                ShowDrawRectangle();
                if (x == e.Location.X && y == e.Location.Y)
                {
                    thDraw.Abort();
                    //ShowDrawRectangle();
                }
                //else
                //{
                //    thDraw.Abort();
                //}
                x = e.Location.X;
                y = e.Location.Y;
                #endregion

                #region 设置局部放大位置随鼠标移动
                if (e.Y <= pictureBox1.Size.Height / 2)
                {
                    if (e.X >= pictureBox1.Size.Width / 4 * 3)
                    {
                        if (IsMouseWheel)
                            pictureBox2.Location = new Point(pictureBox1.Location.X + e.Location.X - 250, pictureBox1.Location.Y + e.Location.Y + 50);
                        else
                            pictureBox2.Location = new Point(e.Location.X - 250, e.Location.Y + 50);
                    }
                    else if (e.X <= pictureBox1.Size.Width / 4)
                    {
                        if (IsMouseWheel)
                            pictureBox2.Location = new Point(pictureBox1.Location.X + e.Location.X + 100, pictureBox1.Location.Y + e.Location.Y + 50);
                        else
                            pictureBox2.Location = new Point(e.Location.X + 100, e.Location.Y + 50);
                    }
                    else
                    {
                        if (IsMouseWheel)
                            // pictureBox2.Location = new Point(Convert.ToInt32(e.Location.X / step) + 50, Convert.ToInt32(e.Location.Y / step) + 50);
                            pictureBox2.Location = new Point(pictureBox1.Location.X + e.Location.X + 50, pictureBox1.Location.Y + e.Location.Y + 50);

                        else
                            pictureBox2.Location = new Point(e.Location.X + 50, e.Location.Y + 50);
                    }
                }
                else
                {
                    if (e.X >= pictureBox1.Size.Width / 4 * 3)
                    {
                        if (IsMouseWheel)
                            pictureBox2.Location = new Point(pictureBox1.Location.X + e.Location.X - 200, pictureBox1.Location.Y + e.Location.Y - 250);
                        else
                            pictureBox2.Location = new Point(e.Location.X - 250, e.Location.Y - 250);
                    }
                    else if (e.X <= pictureBox1.Size.Width / 4)
                    {
                        if (IsMouseWheel)
                            pictureBox2.Location = new Point(pictureBox1.Location.X + e.Location.X + 100, pictureBox1.Location.Y + e.Location.Y - 250);
                        else
                            pictureBox2.Location = new Point(e.Location.X + 100, e.Location.Y - 250);
                    }
                    else
                    {
                        if (IsMouseWheel)
                            pictureBox2.Location = new Point(pictureBox1.Location.X + e.Location.X - 100, pictureBox1.Location.Y + e.Location.Y - 200);
                        //pictureBox2.Location = new Point(Convert.ToInt32(e.Location.X / step) - 50, Convert.ToInt32(e.Location.Y / step) - 250);
                        else
                            pictureBox2.Location = new Point(e.Location.X - 50, e.Location.Y - 250);
                    }
                }
                #endregion           

                #region 图片放大镜

                if (e.X - 25 <= 0)
                {
                    ptBegin.X = 0;
                }
                else if (pictureBox1.Size.Width - e.X <= 25)
                {
                    ptBegin.X = pictureBox1.Size.Width - 50;
                }
                else
                {
                    ptBegin.X = e.X - 25;
                }

                if (e.Y - 25 <= 0)
                {
                    ptBegin.Y = 0;
                }
                else if (pictureBox1.Size.Height - e.Y <= 25)
                {
                    ptBegin.Y = pictureBox1.Size.Height - 50;
                }
                else
                {
                    ptBegin.Y = e.Y - 25;
                }
                pictureBox1.Refresh();

                #endregion
            }
        }

        private void pictureBox1_MouseUp(object sender, MouseEventArgs e)
        {
            if (e.Button == MouseButtons.Left)
            {
                isMouseDown = false;
            }
        }

        private void pictureBox1_MouseDown(object sender, MouseEventArgs e)
        {
            if (e.Button == MouseButtons.Left)
            {
                mouseOffset.X = e.X;
                mouseOffset.Y = e.Y;
                isMouseDown = true;
            }
            else if (e.Button == MouseButtons.Right)//右键（右击）
            {
                pictureBox1.Width = panel1.Width;
                pictureBox1.Height = panel1.Height;
                pictureBox1.Location = new Point(0, 0);
                Width_Pic1 = pictureBox1.Width;
                Height_Pic2 = pictureBox1.Height;
                IsMouseWheel = false;
            }
        }

        #endregion

        #region 图片放大镜

        private void pictureBox1_Paint(object sender, PaintEventArgs e)
        {
            if (blIsDrawRectangle)
            {
                e.Graphics.DrawRectangle(new Pen(Brushes.Blue, 1), ptBegin.X, ptBegin.Y, 50, 50);
            }
            else
            {
                Graphics g = this.CreateGraphics();
            }
        }

        private void ShowDrawRectangle()
        {          
            Rectangle rec = new Rectangle(ptBegin.X * pictureBox1.Image.Size.Width / Width_Pic1, ptBegin.Y * pictureBox1.Image.Size.Height / Height_Pic2,
                                           50 * pictureBox1.Image.Size.Width / Width_Pic1, 50 * pictureBox1.Image.Size.Height / Height_Pic2);
            Graphics g = pictureBox2.CreateGraphics();       
            g.DrawImage(pictureBox1.Image, pictureBox2.ClientRectangle, rec, GraphicsUnit.Pixel);
            //设置蓝色边框
            int bordwidth = Convert.ToInt32(pictureBox2.Width * 0.1);
            int bordheight = Convert.ToInt32(pictureBox2.Height * 0.1);
            int newheight = pictureBox2.Height + bordheight;
            int newwidth = pictureBox2.Width + bordwidth;
            g.DrawRectangle(new Pen(Color.Blue, bordheight), -10, -10, newwidth, newheight);
            g.Flush();
        }

        private void Run()
        {
            while (true)
            {
                if (pictureBox1.Image != null)
                {
                    try
                    {
                            this.BeginInvoke(myDraw);
                    }
                    finally
                    {
                        //this.Close();
                    }
                }
                Thread.Sleep(50);
            }
        }

        private void pictureBox1_MouseLeave(object sender, EventArgs e)
        {
            if (IsShowDrawRect)
            {
                blIsDrawRectangle = false;
                pictureBox1.Refresh();
            }
        }

        private void pictureBox1_MouseEnter(object sender, EventArgs e)
        {
            if (IsShowDrawRect)           
                blIsDrawRectangle = true;
        }

        #endregion

        private void 打印ToolStripMenuItem_Click(object sender, EventArgs e)
        {
            string printname = "";
            DialogResult result = printDialog1.ShowDialog();
            if (result == DialogResult.OK)
                printname = printDialog1.PrinterSettings.PrinterName;
            else
                return;

            //获取或设置一个值，该值指示是否发送到文件或端口     
            printDocument1.PrinterSettings.PrintToFile = true;
            //设置打印时横向还是纵向          
            printDocument1.DefaultPageSettings.Landscape = true;

            printDocument1.PrinterSettings.PrinterName = printname;
            //打印预览         
            // PrintPreviewDialog ppd = new PrintPreviewDialog();      
            if (pictureBox1 == null)
                return;
            //设置边距         
            Margins margin = new Margins(0, 20, 20, 0);
            printDocument1.DefaultPageSettings.Margins = margin;
            //纸张设置默认          
            //PaperSize pageSize = new PaperSize("First custom size", 800, 600);  
            //pd.DefaultPageSettings.PaperSize = pageSize; 
            //设置A4
            //PaperSize pageSize = new PaperSize();
            //foreach (PaperSize ps in printDocument1.PrinterSettings.PaperSizes)
            //{
            //    if (ps.PaperName.Equals("A4"))
            //    {
            //        pageSize = ps;
            //        break;
            //    }
            //}
            //printDocument1.DefaultPageSettings.PaperSize = pageSize;
            //打印事件设置           
            printDocument1.PrintPage += new PrintPageEventHandler(this.pd_PrintPage);

            //ppd.Document = printDocument1;        
            //ppd.ShowDialog();  
         
            try
            {
                printDocument1.Print();
                XtraMessageBox.Show("图片打印成功！", "提示", MessageBoxButtons.OK, MessageBoxIcon.Information);
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message, "打印出错", MessageBoxButtons.OK, MessageBoxIcon.Error);
                printDocument1.PrintController.OnEndPrint(printDocument1, new PrintEventArgs());
            }
        }
        private void pd_PrintPage(object sender, PrintPageEventArgs e)
        {          
            int x = e.MarginBounds.X;
            int y = e.MarginBounds.Y;
            int width = pictureBox1.Height;
            int height = pictureBox1.Width;
            Bitmap bitmap = GetThumbnail((Bitmap)pictureBox1.Image, width, height);//设计到缩放，需重绘图片
            Rectangle destRect = new Rectangle(x, y, bitmap.Width, bitmap.Height);
            e.Graphics.DrawImage(bitmap, destRect, 0, 0, bitmap.Width, bitmap.Height, System.Drawing.GraphicsUnit.Pixel);

        }
        public static Bitmap GetThumbnail(Bitmap b, int destHeight, int destWidth)
        {
            System.Drawing.Image imgSource = b;
            System.Drawing.Imaging.ImageFormat thisFormat = imgSource.RawFormat;
            int sW = 0, sH = 0;
            // 按比例缩放
            int sWidth = imgSource.Width;
            int sHeight = imgSource.Height;

            if (sHeight > destHeight || sWidth > destWidth)
            {
                if ((sWidth * destHeight) > (sHeight * destWidth))
                {
                    sW = destWidth;
                    sH = (destWidth * sHeight) / sWidth;
                }
                else
                {
                    sH = destHeight;
                    sW = (sWidth * destHeight) / sHeight;
                }
            }
            else
            {
                sW = sWidth;
                sH = sHeight;
            }
            Bitmap outBmp = new Bitmap(destWidth, destHeight);
            Graphics g = Graphics.FromImage(outBmp);
            g.Clear(Color.Transparent);

            // 设置画布的描绘质量
            g.CompositingQuality = CompositingQuality.HighQuality;
            g.SmoothingMode = SmoothingMode.HighQuality;
            g.InterpolationMode = InterpolationMode.HighQualityBicubic;

            //g.DrawImage(imgSource, new Rectangle((destWidth - sW) / 2, (destHeight - sH) / 2, sW, sH), 0, 0, imgSource.Width, imgSource.Height, GraphicsUnit.Pixel);
           //无需设置图片的X,Y坐标，不然会显示不完整
            g.DrawImage(imgSource, new Rectangle(0, 0, sW, sH), 0, 0, imgSource.Width, imgSource.Height, GraphicsUnit.Pixel);
            g.Dispose();

            // 以下代码为保存图片时，设置压缩质量
            EncoderParameters encoderParams = new EncoderParameters();
            long[] quality = new long[1];
            quality[0] = 100;

            EncoderParameter encoderParam = new EncoderParameter(System.Drawing.Imaging.Encoder.Quality, quality);
            encoderParams.Param[0] = encoderParam;

            // imgSource.Dispose();

            return outBmp;
        }
        private void 关闭ToolStripMenuItem_Click(object sender, EventArgs e)
        {
            this.Close();
        }

        private void frmMES_Layout_Operation_FormClosed(object sender, FormClosedEventArgs e)
        {
            if (thDraw != null)
            {
                thDraw.Abort();
            }
        }

        private void 取消显示局部放大ToolStripMenuItem_Click(object sender, EventArgs e)
        {
            IsShowDrawRect = !IsShowDrawRect;
            if (!IsShowDrawRect)
            {
                取消显示局部放大ToolStripMenuItem.Text = "显示局部放大";
                pictureBox2.Visible = false;
                blIsDrawRectangle = false;
            }
            else
            {

                取消显示局部放大ToolStripMenuItem.Text = "取消局部放大";
                pictureBox2.Visible = true;
                blIsDrawRectangle = true;
                myDraw = new myDrawRectangel(ShowDrawRectangle);
                thDraw = new Thread(Run);
                thDraw.Start();
            }
        }

        private void pictureBox2_Paint(object sender, PaintEventArgs e)
        {
            PictureBox p = (PictureBox)sender;
            Pen pp = new Pen(Color.Green);
            e.Graphics.DrawRectangle(pp, e.ClipRectangle.X, e.ClipRectangle.Y,
            e.ClipRectangle.X + e.ClipRectangle.Width - 1,
            e.ClipRectangle.Y + e.ClipRectangle.Height - 1);
        }    
    }
}